🩺 Classificação de Câncer de Pele utilizando CNN¶
Este notebook realiza o treinamento, avaliação e visualização com Grad-CAM de um modelo baseado em MobileNetV2 para classificação de imagens dermatológicas.
Todas as seções estão nomeadas em português para facilitar a compreensão do fluxo de trabalho.
📦 Importação das Bibliotecas¶
In [13]:
# Instalar dependências (execute apenas se necessário)
!pip install -q pandas numpy matplotlib seaborn scikit-learn tensorflow shap opencv-python pillow tqdm nbformat
In [14]:
import os
from pathlib import Path
import glob
import numpy as np
import pandas as pd
from PIL import Image
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.models import Model
from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout
from tensorflow.keras.optimizers import Adam
import cv2
import warnings
from sklearn.utils.class_weight import compute_class_weight
import numpy as np
warnings.filterwarnings("ignore", category=UserWarning, module="keras.src.trainers.data_adapters.py_dataset_adapter")
# Garantir comportamento determinístico
np.random.seed(42)
print('Imports carregados')
Imports carregados
📂 Carregamento e Preparação dos Dados¶
In [15]:
# Detectar automaticamente o dataset e realizar download
def find_latest_kagglehub_dataset(base_dir_name='farjanakabirsamanta/skin-cancer-dataset'):
home = Path.home()
cache_base = home / '.cache' / 'kagglehub' / 'datasets'
if cache_base.exists():
candidates = list(cache_base.glob(f'**/{base_dir_name}'))
if not candidates:
candidates = list(cache_base.glob('**/skin-cancer-dataset'))
if candidates:
# ordenar por profundidade e escolher o primeiro mais provável
candidates.sort(key=lambda p: (str(p).count(os.sep), p.name), reverse=True)
return Path(candidates[0])
# fallback: procurar no diretório atual
cwd = Path.cwd()
csvs = list(cwd.glob('**/HAM10000_metadata.csv'))
if csvs:
return csvs[0].parent
raise FileNotFoundError('Dataset HAM10000 não encontrado. Coloque o CSV e imagens na pasta do projeto ou no cache do kagglehub.')
dataset_base = find_latest_kagglehub_dataset()
In [16]:
# Carregar metadados e resolver caminhos das imagens
metadata_path = list(dataset_base.glob('**/HAM10000_metadata.csv'))[0]
metadata = pd.read_csv(metadata_path)
# Mapear diagnósticos
mapping = {
'akiec': 'Queratose actínica',
'bcc': 'Carcinoma basocelular',
'bkl': 'Lesão benigna tipo queratose', # Ou: Queratose seborreica (dependendo do contexto exato do bkl)
'df': 'Dermatofibroma',
'mel': 'Melanoma',
'nv': 'Nevo melanocítico', # Popularmente 'pinta'
'vasc': 'Lesão vascular'
}
metadata['diagnosis'] = metadata['dx'].map(mapping)
## Renomear Colunas
# Mapeamento do nome da coluna original (inglês/código) para o nome desejado (Pt-Br)
column_rename_map = {
'lesion_id': 'id_lesao',
'image_id': 'image_id',
'dx': 'codigo_diagnostico', # O código de diagnóstico original (ex: nv, mel)
'dx_type': 'tipo_diagnostico',
'age': 'idade',
'sex': 'sexo',
'localization': 'localizacao',
'diagnosis': 'diagnostico', # O diagnóstico mapeado por extenso
'image_path': 'image_path'
}
# Aplicar o renomeio
metadata = metadata.rename(columns=column_rename_map)
# localizar pasta de imagens: procurar pastas com muitas imagens
image_folders = [p for p in dataset_base.glob('**/*') if p.is_dir()]
best = None
best_count = 0
for p in image_folders:
count = len(list(p.glob('*.jpg')))
if count > best_count:
best = p
best_count = count
if best is None or best_count == 0:
raise FileNotFoundError('Pasta de imagens não encontrada no dataset base: ' + str(dataset_base))
images_root = best
# construir caminho completo
def resolve_image_path(image_id, images_root):
for ext in ('.jpg', '.jpeg', '.png'):
candidate = images_root / f"{image_id}{ext}"
if candidate.exists():
return str(candidate)
# procurar recursivamente
found = list(images_root.rglob(f"{image_id}.*"))
return str(found[0]) if found else None
metadata['image_path'] = metadata['image_id'].apply(lambda x: resolve_image_path(x, images_root))
metadata = metadata[metadata['image_path'].notnull()].reset_index(drop=True)
# Mapeamento dos valores de sexo
sexo_mapping = {
'male': 'masculino',
'female': 'feminino',
'unknown': 'desconhecido' # Incluindo o valor 'unknown' (desconhecido) por segurança
}
# Aplicar o mapeamento de tradução à coluna 'sexo'
metadata['sexo'] = metadata['sexo'].replace(sexo_mapping)
print('Registros carregados:', len(metadata))
metadata.head()
Registros carregados: 10015
Out[16]:
| id_lesao | image_id | codigo_diagnostico | tipo_diagnostico | idade | sexo | localizacao | diagnostico | image_path | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | HAM_0000118 | ISIC_0027419 | bkl | histo | 80.0 | masculino | scalp | Lesão benigna tipo queratose | C:\Users\flmli\.cache\kagglehub\datasets\farja... |
| 1 | HAM_0000118 | ISIC_0025030 | bkl | histo | 80.0 | masculino | scalp | Lesão benigna tipo queratose | C:\Users\flmli\.cache\kagglehub\datasets\farja... |
| 2 | HAM_0002730 | ISIC_0026769 | bkl | histo | 80.0 | masculino | scalp | Lesão benigna tipo queratose | C:\Users\flmli\.cache\kagglehub\datasets\farja... |
| 3 | HAM_0002730 | ISIC_0025661 | bkl | histo | 80.0 | masculino | scalp | Lesão benigna tipo queratose | C:\Users\flmli\.cache\kagglehub\datasets\farja... |
| 4 | HAM_0001466 | ISIC_0031633 | bkl | histo | 75.0 | masculino | ear | Lesão benigna tipo queratose | C:\Users\flmli\.cache\kagglehub\datasets\farja... |
🔍 Exploração de Dados¶
In [17]:
plt.figure(figsize=(10,5))
sns.countplot(data=metadata, x='diagnostico', order=metadata['diagnostico'].value_counts().index)
plt.xticks(rotation=45)
plt.title('Distribuição das classes')
plt.show()
unique_labels = metadata['diagnostico'].unique()
cols = 4
rows = (len(unique_labels) + cols - 1) // cols
plt.figure(figsize=(4*cols, 4*rows))
for i, label in enumerate(unique_labels):
subset = metadata[metadata['diagnostico'] == label]
if subset.empty:
continue
sample_row = subset.sample(1, random_state=42).iloc[0]
img = Image.open(sample_row['image_path']).convert('RGB')
plt.subplot(rows, cols, i+1)
plt.imshow(img.resize((256,256)))
plt.title(label)
plt.axis('off')
plt.tight_layout()
🧠 Criação e Treinamento do Modelo MobileNetV2¶
In [18]:
le = LabelEncoder()
metadata['label'] = le.fit_transform(metadata['diagnostico'])
train_df, temp_df = train_test_split(metadata, stratify=metadata['label'], test_size=0.25, random_state=42)
val_df, test_df = train_test_split(temp_df, stratify=temp_df['label'], test_size=0.5, random_state=42)
IMG_SIZE = (224,224)
BATCH_SIZE = 32
train_datagen = ImageDataGenerator(rescale=1./255, rotation_range=20, width_shift_range=0.1, height_shift_range=0.1, zoom_range=0.1, horizontal_flip=True)
val_datagen = ImageDataGenerator(rescale=1./255)
train_gen = train_datagen.flow_from_dataframe(train_df, x_col='image_path', y_col='diagnostico', target_size=IMG_SIZE, class_mode='categorical', batch_size=BATCH_SIZE)
val_gen = val_datagen.flow_from_dataframe(val_df, x_col='image_path', y_col='diagnostico', target_size=IMG_SIZE, class_mode='categorical', batch_size=BATCH_SIZE)
test_gen = val_datagen.flow_from_dataframe(test_df, x_col='image_path', y_col='diagnostico', target_size=IMG_SIZE, class_mode='categorical', batch_size=BATCH_SIZE, shuffle=False)
Found 7511 validated image filenames belonging to 7 classes. Found 1252 validated image filenames belonging to 7 classes. Found 1252 validated image filenames belonging to 7 classes.
In [19]:
base = MobileNetV2(weights='imagenet', include_top=False, input_shape=(IMG_SIZE[0], IMG_SIZE[1], 3))
for layer in base.layers:
layer.trainable = False
x = GlobalAveragePooling2D()(base.output)
x = Dropout(0.3)(x)
num_classes = len(train_gen.class_indices)
outputs = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=base.input, outputs=outputs)
model.compile(optimizer=Adam(1e-4), loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
Model: "functional_7"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ input_layer_1 (InputLayer) │ (None, 224, 224, 3) │ 0 │ - │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ Conv1 (Conv2D) │ (None, 112, 112, 32) │ 864 │ input_layer_1[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ bn_Conv1 (BatchNormalization) │ (None, 112, 112, 32) │ 128 │ Conv1[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ Conv1_relu (ReLU) │ (None, 112, 112, 32) │ 0 │ bn_Conv1[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ expanded_conv_depthwise │ (None, 112, 112, 32) │ 288 │ Conv1_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ expanded_conv_depthwise_BN │ (None, 112, 112, 32) │ 128 │ expanded_conv_depthwise[0… │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ expanded_conv_depthwise_relu │ (None, 112, 112, 32) │ 0 │ expanded_conv_depthwise_B… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ expanded_conv_project │ (None, 112, 112, 16) │ 512 │ expanded_conv_depthwise_r… │ │ (Conv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ expanded_conv_project_BN │ (None, 112, 112, 16) │ 64 │ expanded_conv_project[0][… │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_expand (Conv2D) │ (None, 112, 112, 96) │ 1,536 │ expanded_conv_project_BN[… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_expand_BN │ (None, 112, 112, 96) │ 384 │ block_1_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_expand_relu (ReLU) │ (None, 112, 112, 96) │ 0 │ block_1_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_pad (ZeroPadding2D) │ (None, 113, 113, 96) │ 0 │ block_1_expand_relu[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_depthwise │ (None, 56, 56, 96) │ 864 │ block_1_pad[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_depthwise_BN │ (None, 56, 56, 96) │ 384 │ block_1_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_depthwise_relu (ReLU) │ (None, 56, 56, 96) │ 0 │ block_1_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_project (Conv2D) │ (None, 56, 56, 24) │ 2,304 │ block_1_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_1_project_BN │ (None, 56, 56, 24) │ 96 │ block_1_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_expand (Conv2D) │ (None, 56, 56, 144) │ 3,456 │ block_1_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_expand_BN │ (None, 56, 56, 144) │ 576 │ block_2_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_expand_relu (ReLU) │ (None, 56, 56, 144) │ 0 │ block_2_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_depthwise │ (None, 56, 56, 144) │ 1,296 │ block_2_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_depthwise_BN │ (None, 56, 56, 144) │ 576 │ block_2_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_depthwise_relu (ReLU) │ (None, 56, 56, 144) │ 0 │ block_2_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_project (Conv2D) │ (None, 56, 56, 24) │ 3,456 │ block_2_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_project_BN │ (None, 56, 56, 24) │ 96 │ block_2_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_2_add (Add) │ (None, 56, 56, 24) │ 0 │ block_1_project_BN[0][0], │ │ │ │ │ block_2_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_expand (Conv2D) │ (None, 56, 56, 144) │ 3,456 │ block_2_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_expand_BN │ (None, 56, 56, 144) │ 576 │ block_3_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_expand_relu (ReLU) │ (None, 56, 56, 144) │ 0 │ block_3_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_pad (ZeroPadding2D) │ (None, 57, 57, 144) │ 0 │ block_3_expand_relu[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_depthwise │ (None, 28, 28, 144) │ 1,296 │ block_3_pad[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_depthwise_BN │ (None, 28, 28, 144) │ 576 │ block_3_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_depthwise_relu (ReLU) │ (None, 28, 28, 144) │ 0 │ block_3_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_project (Conv2D) │ (None, 28, 28, 32) │ 4,608 │ block_3_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_3_project_BN │ (None, 28, 28, 32) │ 128 │ block_3_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_expand (Conv2D) │ (None, 28, 28, 192) │ 6,144 │ block_3_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_expand_BN │ (None, 28, 28, 192) │ 768 │ block_4_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_expand_relu (ReLU) │ (None, 28, 28, 192) │ 0 │ block_4_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_depthwise │ (None, 28, 28, 192) │ 1,728 │ block_4_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_depthwise_BN │ (None, 28, 28, 192) │ 768 │ block_4_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_depthwise_relu (ReLU) │ (None, 28, 28, 192) │ 0 │ block_4_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_project (Conv2D) │ (None, 28, 28, 32) │ 6,144 │ block_4_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_project_BN │ (None, 28, 28, 32) │ 128 │ block_4_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_4_add (Add) │ (None, 28, 28, 32) │ 0 │ block_3_project_BN[0][0], │ │ │ │ │ block_4_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_expand (Conv2D) │ (None, 28, 28, 192) │ 6,144 │ block_4_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_expand_BN │ (None, 28, 28, 192) │ 768 │ block_5_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_expand_relu (ReLU) │ (None, 28, 28, 192) │ 0 │ block_5_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_depthwise │ (None, 28, 28, 192) │ 1,728 │ block_5_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_depthwise_BN │ (None, 28, 28, 192) │ 768 │ block_5_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_depthwise_relu (ReLU) │ (None, 28, 28, 192) │ 0 │ block_5_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_project (Conv2D) │ (None, 28, 28, 32) │ 6,144 │ block_5_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_project_BN │ (None, 28, 28, 32) │ 128 │ block_5_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_5_add (Add) │ (None, 28, 28, 32) │ 0 │ block_4_add[0][0], │ │ │ │ │ block_5_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_expand (Conv2D) │ (None, 28, 28, 192) │ 6,144 │ block_5_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_expand_BN │ (None, 28, 28, 192) │ 768 │ block_6_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_expand_relu (ReLU) │ (None, 28, 28, 192) │ 0 │ block_6_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_pad (ZeroPadding2D) │ (None, 29, 29, 192) │ 0 │ block_6_expand_relu[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_depthwise │ (None, 14, 14, 192) │ 1,728 │ block_6_pad[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_depthwise_BN │ (None, 14, 14, 192) │ 768 │ block_6_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_depthwise_relu (ReLU) │ (None, 14, 14, 192) │ 0 │ block_6_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_project (Conv2D) │ (None, 14, 14, 64) │ 12,288 │ block_6_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_6_project_BN │ (None, 14, 14, 64) │ 256 │ block_6_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_expand (Conv2D) │ (None, 14, 14, 384) │ 24,576 │ block_6_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_expand_BN │ (None, 14, 14, 384) │ 1,536 │ block_7_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_expand_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_7_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_depthwise │ (None, 14, 14, 384) │ 3,456 │ block_7_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_depthwise_BN │ (None, 14, 14, 384) │ 1,536 │ block_7_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_depthwise_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_7_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_project (Conv2D) │ (None, 14, 14, 64) │ 24,576 │ block_7_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_project_BN │ (None, 14, 14, 64) │ 256 │ block_7_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_7_add (Add) │ (None, 14, 14, 64) │ 0 │ block_6_project_BN[0][0], │ │ │ │ │ block_7_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_expand (Conv2D) │ (None, 14, 14, 384) │ 24,576 │ block_7_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_expand_BN │ (None, 14, 14, 384) │ 1,536 │ block_8_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_expand_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_8_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_depthwise │ (None, 14, 14, 384) │ 3,456 │ block_8_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_depthwise_BN │ (None, 14, 14, 384) │ 1,536 │ block_8_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_depthwise_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_8_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_project (Conv2D) │ (None, 14, 14, 64) │ 24,576 │ block_8_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_project_BN │ (None, 14, 14, 64) │ 256 │ block_8_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_8_add (Add) │ (None, 14, 14, 64) │ 0 │ block_7_add[0][0], │ │ │ │ │ block_8_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_expand (Conv2D) │ (None, 14, 14, 384) │ 24,576 │ block_8_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_expand_BN │ (None, 14, 14, 384) │ 1,536 │ block_9_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_expand_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_9_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_depthwise │ (None, 14, 14, 384) │ 3,456 │ block_9_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_depthwise_BN │ (None, 14, 14, 384) │ 1,536 │ block_9_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_depthwise_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_9_depthwise_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_project (Conv2D) │ (None, 14, 14, 64) │ 24,576 │ block_9_depthwise_relu[0]… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_project_BN │ (None, 14, 14, 64) │ 256 │ block_9_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_9_add (Add) │ (None, 14, 14, 64) │ 0 │ block_8_add[0][0], │ │ │ │ │ block_9_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_expand (Conv2D) │ (None, 14, 14, 384) │ 24,576 │ block_9_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_expand_BN │ (None, 14, 14, 384) │ 1,536 │ block_10_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_expand_relu (ReLU) │ (None, 14, 14, 384) │ 0 │ block_10_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_depthwise │ (None, 14, 14, 384) │ 3,456 │ block_10_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_depthwise_BN │ (None, 14, 14, 384) │ 1,536 │ block_10_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_depthwise_relu │ (None, 14, 14, 384) │ 0 │ block_10_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_project (Conv2D) │ (None, 14, 14, 96) │ 36,864 │ block_10_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_10_project_BN │ (None, 14, 14, 96) │ 384 │ block_10_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_expand (Conv2D) │ (None, 14, 14, 576) │ 55,296 │ block_10_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_expand_BN │ (None, 14, 14, 576) │ 2,304 │ block_11_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_expand_relu (ReLU) │ (None, 14, 14, 576) │ 0 │ block_11_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_depthwise │ (None, 14, 14, 576) │ 5,184 │ block_11_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_depthwise_BN │ (None, 14, 14, 576) │ 2,304 │ block_11_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_depthwise_relu │ (None, 14, 14, 576) │ 0 │ block_11_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_project (Conv2D) │ (None, 14, 14, 96) │ 55,296 │ block_11_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_project_BN │ (None, 14, 14, 96) │ 384 │ block_11_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_11_add (Add) │ (None, 14, 14, 96) │ 0 │ block_10_project_BN[0][0], │ │ │ │ │ block_11_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_expand (Conv2D) │ (None, 14, 14, 576) │ 55,296 │ block_11_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_expand_BN │ (None, 14, 14, 576) │ 2,304 │ block_12_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_expand_relu (ReLU) │ (None, 14, 14, 576) │ 0 │ block_12_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_depthwise │ (None, 14, 14, 576) │ 5,184 │ block_12_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_depthwise_BN │ (None, 14, 14, 576) │ 2,304 │ block_12_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_depthwise_relu │ (None, 14, 14, 576) │ 0 │ block_12_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_project (Conv2D) │ (None, 14, 14, 96) │ 55,296 │ block_12_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_project_BN │ (None, 14, 14, 96) │ 384 │ block_12_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_12_add (Add) │ (None, 14, 14, 96) │ 0 │ block_11_add[0][0], │ │ │ │ │ block_12_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_expand (Conv2D) │ (None, 14, 14, 576) │ 55,296 │ block_12_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_expand_BN │ (None, 14, 14, 576) │ 2,304 │ block_13_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_expand_relu (ReLU) │ (None, 14, 14, 576) │ 0 │ block_13_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_pad (ZeroPadding2D) │ (None, 15, 15, 576) │ 0 │ block_13_expand_relu[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_depthwise │ (None, 7, 7, 576) │ 5,184 │ block_13_pad[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_depthwise_BN │ (None, 7, 7, 576) │ 2,304 │ block_13_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_depthwise_relu │ (None, 7, 7, 576) │ 0 │ block_13_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_project (Conv2D) │ (None, 7, 7, 160) │ 92,160 │ block_13_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_13_project_BN │ (None, 7, 7, 160) │ 640 │ block_13_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_expand (Conv2D) │ (None, 7, 7, 960) │ 153,600 │ block_13_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_expand_BN │ (None, 7, 7, 960) │ 3,840 │ block_14_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_expand_relu (ReLU) │ (None, 7, 7, 960) │ 0 │ block_14_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_depthwise │ (None, 7, 7, 960) │ 8,640 │ block_14_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_depthwise_BN │ (None, 7, 7, 960) │ 3,840 │ block_14_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_depthwise_relu │ (None, 7, 7, 960) │ 0 │ block_14_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_project (Conv2D) │ (None, 7, 7, 160) │ 153,600 │ block_14_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_project_BN │ (None, 7, 7, 160) │ 640 │ block_14_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_14_add (Add) │ (None, 7, 7, 160) │ 0 │ block_13_project_BN[0][0], │ │ │ │ │ block_14_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_expand (Conv2D) │ (None, 7, 7, 960) │ 153,600 │ block_14_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_expand_BN │ (None, 7, 7, 960) │ 3,840 │ block_15_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_expand_relu (ReLU) │ (None, 7, 7, 960) │ 0 │ block_15_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_depthwise │ (None, 7, 7, 960) │ 8,640 │ block_15_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_depthwise_BN │ (None, 7, 7, 960) │ 3,840 │ block_15_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_depthwise_relu │ (None, 7, 7, 960) │ 0 │ block_15_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_project (Conv2D) │ (None, 7, 7, 160) │ 153,600 │ block_15_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_project_BN │ (None, 7, 7, 160) │ 640 │ block_15_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_15_add (Add) │ (None, 7, 7, 160) │ 0 │ block_14_add[0][0], │ │ │ │ │ block_15_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_expand (Conv2D) │ (None, 7, 7, 960) │ 153,600 │ block_15_add[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_expand_BN │ (None, 7, 7, 960) │ 3,840 │ block_16_expand[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_expand_relu (ReLU) │ (None, 7, 7, 960) │ 0 │ block_16_expand_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_depthwise │ (None, 7, 7, 960) │ 8,640 │ block_16_expand_relu[0][0] │ │ (DepthwiseConv2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_depthwise_BN │ (None, 7, 7, 960) │ 3,840 │ block_16_depthwise[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_depthwise_relu │ (None, 7, 7, 960) │ 0 │ block_16_depthwise_BN[0][… │ │ (ReLU) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_project (Conv2D) │ (None, 7, 7, 320) │ 307,200 │ block_16_depthwise_relu[0… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ block_16_project_BN │ (None, 7, 7, 320) │ 1,280 │ block_16_project[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ Conv_1 (Conv2D) │ (None, 7, 7, 1280) │ 409,600 │ block_16_project_BN[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ Conv_1_bn │ (None, 7, 7, 1280) │ 5,120 │ Conv_1[0][0] │ │ (BatchNormalization) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ out_relu (ReLU) │ (None, 7, 7, 1280) │ 0 │ Conv_1_bn[0][0] │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ global_average_pooling2d_1 │ (None, 1280) │ 0 │ out_relu[0][0] │ │ (GlobalAveragePooling2D) │ │ │ │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ dropout_1 (Dropout) │ (None, 1280) │ 0 │ global_average_pooling2d_… │ ├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤ │ dense_1 (Dense) │ (None, 7) │ 8,967 │ dropout_1[0][0] │ └───────────────────────────────┴───────────────────────────┴─────────────────┴────────────────────────────┘
Total params: 2,266,951 (8.65 MB)
Trainable params: 8,967 (35.03 KB)
Non-trainable params: 2,257,984 (8.61 MB)
In [24]:
### TREINANDO EPOCHS
classes = list(train_gen.class_indices.keys())
val_counts = pd.Series(y_true).value_counts().reindex(range(len(classes)), fill_value=0)
val_counts.index = classes
print(val_counts)
class_weights = compute_class_weight(
class_weight='balanced',
classes=np.unique(train_gen.classes),
y=train_gen.classes
)
class_weights = dict(enumerate(class_weights))
history = model.fit(
train_gen,
validation_data=val_gen,
epochs=5,
class_weight=class_weights
)
Carcinoma basocelular 65 Dermatofibroma 14 Lesão benigna tipo queratose 138 Lesão vascular 17 Melanoma 139 Nevo melanocítico 838 Queratose actínica 41 Name: count, dtype: int64 Epoch 1/5 235/235 ━━━━━━━━━━━━━━━━━━━━ 76s 314ms/step - accuracy: 0.2182 - loss: 2.1852 - val_accuracy: 0.3730 - val_loss: 1.6862 Epoch 2/5 235/235 ━━━━━━━━━━━━━━━━━━━━ 74s 317ms/step - accuracy: 0.3021 - loss: 1.9530 - val_accuracy: 0.4665 - val_loss: 1.5191 Epoch 3/5 235/235 ━━━━━━━━━━━━━━━━━━━━ 74s 313ms/step - accuracy: 0.3770 - loss: 1.7864 - val_accuracy: 0.4888 - val_loss: 1.4650 Epoch 4/5 235/235 ━━━━━━━━━━━━━━━━━━━━ 78s 331ms/step - accuracy: 0.4059 - loss: 1.6764 - val_accuracy: 0.5535 - val_loss: 1.3455 Epoch 5/5 235/235 ━━━━━━━━━━━━━━━━━━━━ 74s 313ms/step - accuracy: 0.4286 - loss: 1.6348 - val_accuracy: 0.5623 - val_loss: 1.2942
📖 Avaliação¶
In [25]:
preds = model.predict(test_gen)
y_pred = np.argmax(preds, axis=1)
y_true = test_gen.classes
print(classification_report(
y_true,
y_pred,
target_names=list(train_gen.class_indices.keys()),
zero_division=0
))
cm = confusion_matrix(y_true, y_pred)
plt.figure(figsize=(10,8))
ax = sns.heatmap(cm, annot=True, fmt='d', xticklabels=list(train_gen.class_indices.keys()), yticklabels=list(train_gen.class_indices.keys()))
ax.set_xlabel('Predito')
ax.set_ylabel('Real')
plt.xticks(rotation=45)
plt.yticks(rotation=0)
plt.show()
40/40 ━━━━━━━━━━━━━━━━━━━━ 6s 150ms/step precision recall f1-score support Carcinoma basocelular 0.23 0.52 0.32 65 Dermatofibroma 0.04 0.14 0.06 14 Lesão benigna tipo queratose 0.41 0.24 0.30 138 Lesão vascular 0.20 0.82 0.32 17 Melanoma 0.29 0.47 0.36 139 Nevo melanocítico 0.93 0.66 0.77 838 Queratose actínica 0.18 0.34 0.24 41 accuracy 0.57 1252 macro avg 0.33 0.46 0.34 1252 weighted avg 0.72 0.57 0.62 1252
🔥 Funções Grad-CAM¶
In [26]:
# Função para encontrar a última camada convolucional automaticamente
def encontrar_ultima_conv(model):
for layer in reversed(model.layers):
if isinstance(layer, tf.keras.layers.Conv2D):
return layer.name
raise ValueError('Nenhuma camada convolucional encontrada.')
ultima_conv = encontrar_ultima_conv(model)
def gerar_gradcam_heatmap(model, img_array, last_conv_layer_name, pred_index=None):
grad_model = tf.keras.models.Model(model.input, [model.get_layer(last_conv_layer_name).output, model.output])
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
if pred_index is None:
pred_index = tf.argmax(predictions[0])
class_channel = predictions[:, pred_index]
grads = tape.gradient(class_channel, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0,1,2))
conv_outputs = conv_outputs[0].numpy()
pooled_grads = pooled_grads.numpy()
for i in range(pooled_grads.shape[-1]):
conv_outputs[:,:,i] *= pooled_grads[i]
heatmap = np.mean(conv_outputs, axis=-1)
heatmap = np.maximum(heatmap, 0)
heatmap /= (heatmap.max() + 1e-8)
heatmap = cv2.resize(heatmap, (IMG_SIZE[1], IMG_SIZE[0]))
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
return heatmap
def gerar_mapa_gradcam(model, imagem_array, nome_camada_conv):
grad_model = tf.keras.models.Model(
inputs=model.inputs,
outputs=[model.get_layer(nome_camada_conv).output, model.output]
)
with tf.GradientTape() as tape:
conv_output, pred = grad_model(imagem_array)
classe_pred = tf.argmax(pred[0])
loss = pred[:, classe_pred]
grads = tape.gradient(loss, conv_output)[0]
pesos = tf.reduce_mean(grads, axis=(0,1))
gradcam = tf.reduce_sum(tf.multiply(pesos, conv_output[0]), axis=-1)
heatmap = np.maximum(gradcam, 0) / (tf.reduce_max(gradcam) + 1e-8)
heatmap = cv2.resize(heatmap.numpy(), (224,224))
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
return heatmap
🖼️ Visualização Grad-CAM em Lote¶
In [33]:
def gradcam_em_lote(model, df, num_imagens=6):
exemplos = df.sample(num_imagens, random_state=42).reset_index(drop=True)
plt.figure(figsize=(8, num_imagens * 3))
for i, row in exemplos.iterrows():
imagem = load_img(row['image_path'], target_size=IMG_SIZE)
imagem_arr = img_to_array(imagem) / 255.0
entrada = np.expand_dims(imagem_arr, axis=0)
mapa = gerar_mapa_gradcam(model, entrada, ultima_conv)
sobreposta = cv2.addWeighted(np.uint8(imagem_arr*255), 0.6, mapa, 0.4, 0)
plt.subplot(num_imagens, 2, 2*i+1)
plt.imshow(imagem)
plt.title(f'Imagem Original: {row["diagnostico"]}')
plt.axis('off')
plt.subplot(num_imagens, 2, 2*i+2)
plt.imshow(sobreposta)
plt.title('Mapa Grad-CAM')
plt.axis('off')
plt.tight_layout()
In [34]:
gradcam_em_lote(model, test_df, num_imagens=6)
💾 Salvamento do Modelo (formato moderno .keras)¶
In [35]:
model.save('modelo_cancer_pele.keras')
print('Modelo salvo com sucesso!')
Modelo salvo com sucesso!